package host

import (
	"fmt"
	"sync"

	log "github.com/sirupsen/logrus"
	"github.com/yourusername/lvm-manager/internal/libvirtconn"
)

// HostManager 管理多个宿主机连接
type HostManager struct {
	hosts map[string]*libvirtconn.ConnManager
	mu    sync.RWMutex
}

// HostInfo 宿主机信息
type HostInfo struct {
	ID         string `json:"id"`
	URI        string `json:"uri"`
	Connected  bool   `json:"connected"`
	Hypervisor string `json:"hypervisor,omitempty"`
	Version    uint32 `json:"version,omitempty"`
}

// NewHostManager 创建宿主机管理器
func NewHostManager() *HostManager {
	return &HostManager{
		hosts: make(map[string]*libvirtconn.ConnManager),
	}
}

// AddHost 添加宿主机
func (hm *HostManager) AddHost(id, uri string) error {
	hm.mu.Lock()
	defer hm.mu.Unlock()

	// 检查是否已存在
	if _, exists := hm.hosts[id]; exists {
		return fmt.Errorf("host with id %s already exists", id)
	}

	// 创建连接管理器
	connMgr := libvirtconn.NewConnManager(uri)

	// 尝试连接
	if err := connMgr.Connect(); err != nil {
		log.Warnf("Failed to connect to host %s (%s): %v", id, uri, err)
		// 即使连接失败也添加到管理器中，允许后续重连
	}

	hm.hosts[id] = connMgr
	log.Infof("Added host %s with URI %s", id, uri)
	return nil
}

// RemoveHost 移除宿主机
func (hm *HostManager) RemoveHost(id string) error {
	hm.mu.Lock()
	defer hm.mu.Unlock()

	connMgr, exists := hm.hosts[id]
	if !exists {
		return fmt.Errorf("host with id %s not found", id)
	}

	// 关闭连接
	if err := connMgr.Close(); err != nil {
		log.Warnf("Error closing connection to host %s: %v", id, err)
	}

	delete(hm.hosts, id)
	log.Infof("Removed host %s", id)
	return nil
}

// GetHost 获取宿主机连接管理器
func (hm *HostManager) GetHost(id string) (*libvirtconn.ConnManager, error) {
	hm.mu.RLock()
	defer hm.mu.RUnlock()

	connMgr, exists := hm.hosts[id]
	if !exists {
		return nil, fmt.Errorf("host with id %s not found", id)
	}

	return connMgr, nil
}

// ListHosts 列出所有宿主机信息
func (hm *HostManager) ListHosts() []HostInfo {
	hm.mu.RLock()
	defer hm.mu.RUnlock()

	var hosts []HostInfo
	for id, connMgr := range hm.hosts {
		info := HostInfo{
			ID:        id,
			URI:       connMgr.GetURI(), // 使用GetURI方法获取URI
			Connected: connMgr.IsConnected(),
		}

		// 获取连接URI（这里需要添加一个方法到ConnManager）
		// 由于URI字段是私有的，我们需要在ConnManager中添加一个方法来获取它

		if caps := connMgr.GetCapabilities(); caps != nil {
			info.Hypervisor = caps.Hypervisor
			info.Version = caps.LibvirtVersion
		}

		hosts = append(hosts, info)
	}

	return hosts
}

// ConnectHost 连接到指定宿主机
func (hm *HostManager) ConnectHost(id string) error {
	hm.mu.RLock()
	connMgr, exists := hm.hosts[id]
	hm.mu.RUnlock()

	if !exists {
		return fmt.Errorf("host with id %s not found", id)
	}

	return connMgr.Connect()
}

// DisconnectHost 断开指定宿主机连接
func (hm *HostManager) DisconnectHost(id string) error {
	hm.mu.RLock()
	connMgr, exists := hm.hosts[id]
	hm.mu.RUnlock()

	if !exists {
		return fmt.Errorf("host with id %s not found", id)
	}

	return connMgr.Close()
}
